package com.groupbuying.payconsumer.mq;

import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.shade.com.alibaba.fastjson.JSON;
import com.aliyun.openservices.shade.com.alibaba.fastjson.serializer.SerializerFeature;
import com.groupbuying.payconsumer.connector.OrderFeign;
import com.groupbuying.payconsumer.connector.SysconfigFeign;
import com.groupbuying.payconsumer.constants.CommonConstants;
import com.groupbuying.payconsumer.constants.PayInfoEnumConstants;
import com.groupbuying.payconsumer.constants.PayWechatpayResultEnumConstants;
import com.groupbuying.payconsumer.domain.PayInfoDO;
import com.groupbuying.payconsumer.domain.PayOrderRelDO;
import com.groupbuying.payconsumer.domain.PayWechatpayResultDO;
import com.groupbuying.payconsumer.service.PayInfoService;
import com.groupbuying.payconsumer.service.PayOrderRelService;
import com.groupbuying.payconsumer.service.PayWechatpayResultService;
import com.groupbuying.payconsumer.utils.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * 支付中心微信回执监听消费
 *
 * @Author Vincentxin
 * @Date 2019-05-10
 */
@Component
public class WeChatPayResult {
    public static final Logger LOGGER = LoggerFactory.getLogger(WeChatPayResult.class);
    @Autowired
    private PayInfoService payInfoService;

    @Autowired
    private PayOrderRelService payOrderRelService;
    @Autowired
    private PayWechatpayResultService wechatpayResultService;
    @Autowired
    private Producer producer;
    @Autowired
    private OrderFeign orderFeign;
    @Autowired
    private SysconfigFeign sysconfigFeign;

    @Transactional(rollbackFor = Exception.class)
    public boolean dealResult(Map<String,Object> messageBody) {
        //存储支付回执信息
        LOGGER.info("回执消息："+messageBody.toString());
        PayWechatpayResultDO payWxResultDO = new PayWechatpayResultDO();
        payWxResultDO.setId(messageBody.get("out_trade_no").toString());
        payWxResultDO.setResultCode(messageBody.get("result_code").toString());
        payWxResultDO.setTotalFee(new BigDecimal(messageBody.get("total_fee").toString()).divide(new BigDecimal("100")));
        payWxResultDO.setTransactionId(messageBody.get("transaction_id").toString());
        try{
            payWxResultDO.setTimeEnd(DateUtils.parse(messageBody.get("time_end").toString(),"yyyyMMddHHmmss"));
        }catch (Exception e){
            e.printStackTrace();
            LOGGER.error("订单号：" + payWxResultDO.getId() + "，微信内部单号：" + payWxResultDO.getTransactionId()+"TimeEnd时间格式转换错误");
        }
        payWxResultDO.setTradeType(messageBody.get("trade_type").toString());
        payWxResultDO.setGmtModified(new Date());
        payWxResultDO.setGmtCreate(new Date());
        payWxResultDO.setIsDelete(PayWechatpayResultEnumConstants.ENUM_ISDELETE_UNDEL);
        try {
            wechatpayResultService.save(payWxResultDO);
        } catch (DuplicateKeyException exception) {
            //主键冲突之后，更新
            wechatpayResultService.update(payWxResultDO);
            LOGGER.info("订单号：" + payWxResultDO.getId() + "，微信内部单号：" + payWxResultDO.getTransactionId() + "已经保存过了是多次请求");
        }

        //获取支付单信息
        PayInfoDO payInfoDO = payInfoService.get(payWxResultDO.getId());
        //判断回执金额和支付单金额不一致
        if (payInfoDO.getPayMoney().compareTo(payWxResultDO.getTotalFee()) != 0) {
            //TODO 金额不一致对应的处理（作为异常订单处理），暂时记录日志，然后标记消费
            //TODO 发送订单中心冻结交（或许）
            LOGGER.error("订单号：" + payWxResultDO.getId() + "，微信内部单号：" + payWxResultDO.getTransactionId() + "，金额匹配不一致");
            return true;
        }

        //微信支付失败
        if (PayWechatpayResultEnumConstants.ENUM_RESULTCODE_FAIL.equals(payWxResultDO.getResultCode())) {
            //如果支付单的状态不是支付失败
            if (!PayInfoEnumConstants.ENUM_PAYSTATE_FAILPAY.equals(payInfoDO.getPayState())) {
                //强行修改支付单的支付状态为支付失败
                payInfoDO.setPayState(PayInfoEnumConstants.ENUM_PAYSTATE_FAILPAY);
                payInfoDO.setGmtModified(new Date());
                payInfoService.update(payInfoDO);
            }
            //TODO 交易失败的各种处理，如果已经是成功的状态怎么办？
            LOGGER.info("订单号：" + payWxResultDO.getId() + "，微信内部单号：" + payWxResultDO.getTransactionId() + "交易失败");
            return true;
        }

        //微信支付成功
        else if (PayWechatpayResultEnumConstants.ENUM_RESULTCODE_SUCCESS.equals(payWxResultDO.getResultCode())) {
            //查看当前支付单是否已经修改成功
            if (PayInfoEnumConstants.ENUM_PAYSTATE_SUCPAY.equals(payInfoDO.getPayState())) {
                return true;
            }
            payInfoDO.setPayState(PayInfoEnumConstants.ENUM_PAYSTATE_SUCPAY);
            payInfoDO.setGmtModified(new Date());
            payInfoService.update(payInfoDO);
        }
        //获取支付单与订单关联信息
        PayOrderRelDO payOrderRelDO = payOrderRelService.get(payWxResultDO.getId());
        //获取订单信息
        Map orderMap = orderFeign.getOrderForPay(payOrderRelDO.getOrderId());
        //订单是否属于够样优店
        boolean curNotify = orderMap.get("orderId").toString().substring(4,7).equals("000");
        if (curNotify){
            //商户优惠规则
            Map ruleMap = new HashMap();
            ruleMap.put("ruleId", orderMap.get("opxRuleId"));
            ruleMap.put("delFlag", CommonConstants.COMMON_FLAG_UNDEL);
            Map rulesMap = sysconfigFeign.getStoreOpexRule(ruleMap);
            orderMap.putAll(rulesMap);
        }

        //设置订单中心消息传递消息体
        Map<String, Object> orderParam = new HashMap<>();
        orderParam.put("orderId", orderMap.get("orderId"));
        //设置积分中心消息传递消息体
        Map<String, Object> currencyParam = new HashMap<>();
        if (curNotify){
            currencyParam.put("payId",payInfoDO.getId());
            currencyParam.put("customerId", orderMap.get("customerId"));
            currencyParam.put("consumptionAmount", orderMap.get("orderPrice"));
            currencyParam.put("backCurrencyRatio", orderMap.get("backCurrencyRatio"));

        }
        //设置分账中心消息传递内容
        Map<String, Object> settleParam = new HashMap<>();
        settleParam.put("orderId", orderMap.get("orderId"));
        settleParam.put("outTradeNo", payOrderRelDO.getOutTradeNo());
        settleParam.put("ruleId", orderMap.get("opxRuleId"));
        settleParam.put("totalAmount", payInfoDO.getPayMoney());
        //收银台ID
        settleParam.put("counterId", orderMap.get("counterId"));
        //用户ID
        settleParam.put("customerId", orderMap.get("customerId"));
        //支付分账
        settleParam.put("settleType", "0");
        settleParam.put("payType", payInfoDO.getPayType());
        settleParam.put("payChannel", payInfoDO.getPayChannel());

        try {
            //订单中心
            Message orderMessage = new Message(PayMQConfig.ORDER_TOPIC, PayMQConfig.ORDER_TAG_PAY,
                    JSON.toJSONString(orderParam, SerializerFeature.DisableCircularReferenceDetect).getBytes());
            producer.send(orderMessage);
        } catch (Exception e) {
            LOGGER.error("订单号：" + payWxResultDO.getId() + "，微信内部单号：" + payWxResultDO.getTransactionId() + "，发送订单中心失败");
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();

        }
        if (curNotify){
            try{
                //积分中心
                Message currencyMessage = new Message(PayMQConfig.CURRENCY_TOPIC, PayMQConfig.CURRENCY_TAG_ADD,
                        JSON.toJSONString(currencyParam, SerializerFeature.DisableCircularReferenceDetect).getBytes());
                producer.send(currencyMessage);
            } catch (Exception e) {
                LOGGER.error("订单号：" + payWxResultDO.getId() + "，微信内部单号：" + payWxResultDO.getTransactionId() + "，发送积分中心失败");
                e.printStackTrace();
            }
        }

        try{
            //分账中心
            Message settleMessage = new Message(PayMQConfig.SETTLE_TOPIC, PayMQConfig.SETTLE_TAG_SPLIT,
                    JSON.toJSONString(settleParam, SerializerFeature.DisableCircularReferenceDetect).getBytes());
            producer.send(settleMessage);
        } catch (Exception e) {
            LOGGER.error("订单号：" + payWxResultDO.getId() + "，微信内部单号：" + payWxResultDO.getTransactionId() + "，发送分账中心失败");
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
            //发送不成功的话，稍后重试
        }
        return true;
    }

}
